#include <app_config.h>
#include <log_util.h>

#include <QApplication>
#include <QCommandLineParser>
#include <QScreen>

#include "mainwindow.h"
#include "plugin_manager.h"

/**
 * @brief 打印程序配置信息
 */
void printAppConfig();

/**
 * @brief 窗口居中
 * @param w 主窗口实例
 */
void setWindowInCenter(MainWindow &w);

/**
 * @brief 初始化命令行参数
 * 
 * @param app 应用程序实例
 */
void initCommandLine(QApplication &app);

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    LogUtil::init(AppConfig::getInstance()->logLevel(), "../logs/app.log");
    std::shared_ptr<spdlog::logger> log = LogUtil::getLogger("app");
    printAppConfig();

    // 加载程序自带插件
    PluginManager::getInstance()->loadPlugins(AppConfig::getInstance()->pluginsAppDir().absolutePath());
    // 加载用户下载的插件
    PluginManager::getInstance()->loadPlugins(AppConfig::getInstance()->pluginsUserDir().absolutePath());

    initCommandLine(a);
    MainWindow w;
    setWindowInCenter(w);
    w.show();

    SPDLOG_LOGGER_DEBUG(log, fmt::format("hello qt"));

    return a.exec();
}

void printAppConfig() {
    std::shared_ptr<spdlog::logger> log = LogUtil::getLogger("app");
    SPDLOG_LOGGER_DEBUG(log,
                        fmt::format("appConfig[appVersion]:{}", AppConfig::getInstance()->appVersion().toStdString()));
    SPDLOG_LOGGER_DEBUG(
        log, fmt::format("appConfig[appDir]:{}", AppConfig::getInstance()->appDir().absolutePath().toStdString()));
    SPDLOG_LOGGER_DEBUG(
        log, fmt::format("appConfig[dataDir]:{}", AppConfig::getInstance()->dataDir().absolutePath().toStdString()));
    SPDLOG_LOGGER_DEBUG(log, fmt::format("appConfig[pluginsAppDir]:{}",
                                         AppConfig::getInstance()->pluginsAppDir().absolutePath().toStdString()));
    SPDLOG_LOGGER_DEBUG(log,
                        fmt::format("appConfig[logLevel]:{}", static_cast<int>(AppConfig::getInstance()->logLevel())));
}

/**
 * 是否在主屏幕显示
 */
#define SHOW_WINDOW_IN_PRIMARY_SCREEN 1

void setWindowInCenter(MainWindow &w) {
#if SHOW_WINDOW_IN_PRIMARY_SCREEN
    // 获取主屏幕的指针
    QScreen *primaryScreen = QGuiApplication::primaryScreen();
    // 获取主屏幕的可用工作区几何信息
    QRect availableGeometry = primaryScreen->availableGeometry();
#else
    // 获取当前屏幕的可用工作区几何信息
    QScreen *currentScreen     = QGuiApplication::screenAt(w.pos());
    QRect    availableGeometry = currentScreen->availableGeometry();
#endif
    // 计算窗口居中显示的位置
    int x = availableGeometry.x() + (availableGeometry.width() - w.width()) / 2;
    int y = availableGeometry.y() + (availableGeometry.height() - w.height()) / 2;

    // 移动窗口到居中的位置
    w.move(x, y);
}

void initCommandLine(QApplication &app) {
    std::shared_ptr<spdlog::logger> log = LogUtil::getLogger("app");

    QCommandLineParser parser;
    // 创建命令行选项
    QCommandLineOption dataDirOption("data-dir", "用户目录", "<dir>", "");
    parser.addOption(dataDirOption);

    // 解析命令行参数
    parser.process(app);

    // 获取命令行参数值
    QString dataDir = parser.value(dataDirOption);
    if (!dataDir.isEmpty()) {
        AppConfig::getInstance()->dataDir(dataDir);
    }
    SPDLOG_LOGGER_DEBUG(log,
                        fmt::format("dataDir:{}", AppConfig::getInstance()->dataDir().absolutePath().toStdString()));
    SPDLOG_LOGGER_DEBUG(log, fmt::format("appDir:{}", AppConfig::getInstance()->appDir().absolutePath().toStdString()));
}
